/*
 *      mainwindow.cpp
 *      
 *      Copyright 2008 Oliver Eichner <o.eichner@gmail.com>
 *      
 *      This program is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation; either version 2 of the License, or
 *      (at your option) any later version.
 *      
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *      
 *      You should have received a copy of the GNU General Public License
 *      along with this program; if not, write to the Free Software
 *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 *      MA 02110-1301, USA.
 */

/** @file mainwindow.cpp
 *  This file contains main window class for gtableauparm
 */


#include <gtkmm-2.4/gtkmm/toggleaction.h>
#include <gtkmm-2.4/gtkmm/box.h>
#include <gtkmm-2.4/gtkmm/messagedialog.h>

#include "mainwindow.h"

#include "PrintFormOperation.h"
#include "text.h"

/**
 * @brief The main window of tableau-parm GUI
 */
TP_main::TP_main() {
    //Standartfestergröße
    set_default_size(820, 300);

    //set_border_width(10);

    //Titel
    string title;

    title.append(TITLE);
    title.append(" - ");
    title.append(VER);
    set_title(title);
    tpg_ContextId = tpg_Statusbar.get_context_id(title);

    //Widgets in Table einfügen
    attach_widgets_to_table();

    //Tabelle dem Fenster übergenen
    add(tp_VBox);

     set_icon_from_file(APP_ICON32);
    //Alle Widgets anzeigen
    show_all_children();
}

TP_main::~TP_main() {
}

bool TP_main::on_button_press_event(GdkEventButton* event) {
    //Call base class, to allow normal handling,
    //such as allowing the row to be selected by the right-click:
    bool return_value = tp_DeviceTreeView.on_button_press_event(event);

    //Then do our custom stuff:
    if ((event->type == GDK_BUTTON_PRESS) && (event->button == 3)) {
        //tp_Menu_Popup.popup(event->button, event->time);
        cout<<"right click: "<<endl;
    }

    // if middle mouse button is pressed
    if ((event->type == GDK_BUTTON_PRESS) && (event->button == 2)) {
        cout<<"middle click: "<<endl;
    }
    // if left mouse button is pressed
    if ((event->type == GDK_BUTTON_PRESS) && (event->button == 1)) {
        cout<<"left click: "<<endl;
    }
    //FIXME GDK_DOUBLE_BUTTON_PRESS = 5 ???
    if((event->type == 5) && (event->button == 1)) {
        cout<<"double click left: "<<endl;
    }


    return return_value;
}

/**
 * @brief add widgets to the window
 */
//rename!!

void TP_main::attach_widgets_to_table() {
    // treeview in scrolled window
    
    tp_ScrolledWindow.add(tp_DeviceTreeView);
    // scrolled window nur wenn nötiganzeigen
    tp_ScrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
    
   
    //menu/toolbar

    //Create actions for menus and toolbars:
    m_refActionGroup = Gtk::ActionGroup::create();


    //File menu:
    m_refActionGroup->add(Gtk::Action::create("FileMenu", Gtk::Stock::HARDDISK));
    m_refActionGroup->add(Gtk::Action::create("FileQuit", Gtk::Stock::QUIT, "Exit gTableuParm"),
            sigc::mem_fun(*this, &TP_main::on_buttonQuit_clicked));
    //Print
    
    m_refActionGroup->add(
            Gtk::Action::create("SaveTo", Gtk::Stock::SAVE_AS, "Save Devicedetails to file"),
            sigc::mem_fun(*this, &TP_main::on_menu_saveto));

    m_refActionGroup->add(
            Gtk::Action::create("Details", Gtk::Stock::FIND,"Devicedetails", "Show Devicedetails"),
            sigc::mem_fun(*this, &TP_main::on_menu_details));

    
    m_refActionGroup->add(
            Gtk::Action::create("PageSetup", Gtk::Stock::PAGE_SETUP, "Page Setup", "Page Setup" ),
            sigc::mem_fun(*this, &TP_main::on_menu_file_page_setup));

    m_refActionGroup->add(
            Gtk::Action::create("PrintPreview", Gtk::Stock::PRINT_PREVIEW, "Print Preview"),
            sigc::mem_fun(*this, &TP_main::on_menu_file_print_preview));

    m_refActionGroup->add(
            Gtk::Action::create("Print", Gtk::Stock::PRINT, "Print"),
            sigc::mem_fun(*this, &TP_main::on_menu_file_print));

    //Edit menu:
    m_refActionGroup->add(Gtk::Action::create("Refresh", Gtk::Stock::REFRESH, "Refresh Treeview"),
            Gtk::AccelKey("<control><alt>R"),
            sigc::mem_fun(*this, &TP_main::on_buttonRefresh_clicked));
    m_refActionGroup->add(Gtk::Action::create("AddComment", Gtk::Stock::EDIT,"Add Comment", "Add a comment to a device"),
            Gtk::AccelKey("<control><alt>C"),
            sigc::mem_fun(*this, &TP_main::on_menu_addcomment));


    //Choices menu, to demonstrate Radio items
    m_refActionGroup->add(Gtk::Action::create("OptionMenu", Gtk::Stock::PREFERENCES, "Options"));
    //Gtk::ToggleAction::Group group_userlevel;
    m_refActionGroup->add(Gtk::Action::create("TreeView", "TreeView"));
    m_refChoiceBridge = Gtk::ToggleAction::create("Bridge", "Bridge", "test one", TRUE);
    m_refActionGroup->add(m_refChoiceBridge,
            sigc::mem_fun(*this, &TP_main::on_menu_choices_bridge));
    m_refChoiceDevice = Gtk::ToggleAction::create("Device", "Device", "test two", TRUE);
    m_refActionGroup->add(m_refChoiceDevice,
            sigc::mem_fun(*this, &TP_main::on_menu_choices_device));
    m_refChoiceVendor = Gtk::ToggleAction::create("Vendor", "Vendor", "show/hide Vendor", TRUE);
    m_refActionGroup->add(m_refChoiceVendor,
            sigc::mem_fun(*this, &TP_main::on_menu_choices_vendor));
    m_refChoiceModel = Gtk::ToggleAction::create("Model", "Model", "show/hide Model", TRUE);
    m_refActionGroup->add(m_refChoiceModel,
            sigc::mem_fun(*this, &TP_main::on_menu_choices_model));
    m_refChoiceSize = Gtk::ToggleAction::create("Size", "Size", "show/hide Size", TRUE);
    m_refActionGroup->add(m_refChoiceSize,
            sigc::mem_fun(*this, &TP_main::on_menu_choices_size));

    m_refChoiceWriteblk = Gtk::ToggleAction::create("Writeblk", "Writeblocked", "show/hide Writeblocked", TRUE);
    m_refActionGroup->add(m_refChoiceWriteblk,
            sigc::mem_fun(*this, &TP_main::on_menu_choices_writeblk));
    m_refChoiceHpa = Gtk::ToggleAction::create("HPA", "HPA in use", "show/hide HPA in use", TRUE);
    m_refActionGroup->add(m_refChoiceHpa,
            sigc::mem_fun(*this, &TP_main::on_menu_choices_hpa));
    m_refChoiceDco = Gtk::ToggleAction::create("DCO", "DCO in use", "show/hide DCO in use", TRUE);
    m_refActionGroup->add(m_refChoiceDco,
            sigc::mem_fun(*this, &TP_main::on_menu_choices_dco));
    m_refChoiceSec = Gtk::ToggleAction::create("Sec", "Security in use", "show/hide Security in use", TRUE);
    m_refActionGroup->add(m_refChoiceSec,
            sigc::mem_fun(*this, &TP_main::on_menu_choices_sec));
    //Help menu:
    m_refActionGroup->add(Gtk::Action::create("HelpMenu", "Help"));
    m_refActionGroup->add(Gtk::Action::create("Help", Gtk::Stock::HELP),
            sigc::mem_fun(*this, &TP_main::on_menu_others));
    m_refActionGroup->add(Gtk::Action::create("About", Gtk::Stock::ABOUT),
            sigc::mem_fun(*this, &TP_main::on_menu_others));

    m_refUIManager = Gtk::UIManager::create();
    m_refUIManager->insert_action_group(m_refActionGroup);

    add_accel_group(m_refUIManager->get_accel_group());

    //Layout the actions in a menubar and toolbar:
    Glib::ustring ui_info =
            "<ui>"
            "  <menubar name='MenuBar'>"
            "    <menu action='FileMenu'>"
            "      <menuitem action='SaveTo'/>"
            "      <menuitem action='Print'/>"
            "      <menuitem action='PrintPreview'/>"
            "      <menuitem action='PageSetup'/>"
            "      <separator/>"
            "      <menuitem action='Details'/>"
            "      <menuitem action='Refresh'/>"
            "      <menuitem action='AddComment'/>"
            "      <separator/>"
            "      <menuitem action='FileQuit'/>"
            "    </menu>"
            "    <menu action='OptionMenu'>"
            "      <menu action='TreeView'>"
            "       <menuitem action='Bridge'/>"
            "       <menuitem action='Device'/>"
            "       <menuitem action='Vendor'/>"
            "       <menuitem action='Model'/>"
            "       <menuitem action='Size'/>"
            "       <menuitem action='Writeblk'/>"
            "       <menuitem action='HPA'/>"
            "       <menuitem action='DCO'/>"
            "       <menuitem action='Sec'/>"
            "      </menu>"
            "    </menu>"
            "    <menu action='HelpMenu'>"
          //  "      <menuitem action='Help'/>"
            "      <menuitem action='About'/>"
            "    </menu>"
            "  </menubar>"
            "  <toolbar  name='ToolBar'>"
            "    <toolitem action='Refresh'/>"
            "    <separator/>"
            "    <toolitem action='SaveTo'/>"
            "    <toolitem action='Print'/>"
            "    <toolitem action='PrintPreview'/>"
            "    <separator/>"
            "    <toolitem action='Details'/>"
            "    <toolitem action='AddComment'/>"
            "    <separator/>"
            "    <toolitem action='FileQuit'/>"
            "  </toolbar>"
            "</ui>";

#ifdef GLIBMM_EXCEPTIONS_ENABLED
    try {
        m_refUIManager->add_ui_from_string(ui_info);
    } catch (const Glib::Error& ex) {
        std::cerr << "building menus failed: " << ex.what();
    }
#else
    std::auto_ptr<Glib::Error> ex;
    m_refUIManager->add_ui_from_string(ui_info, ex);
    if (ex.get()) {
        std::cerr << "building menus failed: " << ex->what();
    }
#endif //GLIBMM_EXCEPTIONS_ENABLED

    //Get the menubar and toolbar widgets, and add them to a container widget:
    Gtk::Widget* pMenubar = m_refUIManager->get_widget("/MenuBar");
    if (pMenubar)
        tp_VBox.pack_start(*pMenubar, Gtk::PACK_SHRINK);

    Gtk::Widget* pToolbar = m_refUIManager->get_widget("/ToolBar");
    if (pToolbar)
        tp_VBox.pack_start(*pToolbar, Gtk::PACK_SHRINK);



    tp_VBox.pack_start(tp_ScrolledWindow);
    tp_VBox.pack_start(tpg_Statusbar, Gtk::PACK_SHRINK);
    tp_ScrolledWindow.set_border_width(5);

    Glib::ustring stat;
    stat=TITLE;
    tpg_Statusbar.push(stat, tpg_ContextId);


}


/**
 * @brief Fenster Schließen
 */
void TP_main::on_buttonQuit_clicked() {
    hide();
}

/**
 * @brief TreeView Neu  einlesen und zeichnen
 */
void TP_main::on_buttonRefresh_clicked() {

    tp_DeviceTreeView.reload();
    //tp_DeviceTreeView.
}

void TP_main::on_menu_addcomment() {
    if (tp_DeviceTreeView.somethingSelected()) {
        tp_DeviceTreeView.on_menu_file_popup_AddComment();
    } else {
        Gtk::MessageDialog dia(*this, "No device selected!!",false,
                Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, false);
        dia.set_secondary_text("Pleace select a device in the list.");
        dia.set_title("Warning");
        dia.run();
    }
    
}

void TP_main::on_menu_saveto() {
    if (tp_DeviceTreeView.somethingSelected()) {
        tp_DeviceTreeView.on_menu_file_popup_Save();
    } else {
        Gtk::MessageDialog dia(*this, "No device selected!!",false,
                Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, false);
        dia.set_secondary_text("Pleace select a device in the list.");
        dia.set_title("Warning");
        dia.run();
    }
    
}

void TP_main::on_menu_details() {
    if (tp_DeviceTreeView.somethingSelected()) {
        tp_DeviceTreeView.on_menu_file_popup_Details();
    } else {
        Gtk::MessageDialog dia(*this, "No device selected!!",false,
                Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, false);
        dia.set_secondary_text("Pleace select a device in the list.");
        dia.set_title("Warning");
        dia.run();
    }
    
}
//TODO rename function to on_menu_about()
void TP_main::on_menu_others() {
    static Gtk::AboutDialog about;
    about.set_copyright("\xC2\xA9 2008,2009 Oliver Eichner");
    about.set_version(VER);
    about.set_comments("The \"Tableau Disk Monitor\" for linux.");
    about.set_license("General Public License v3");
    about.set_name(TITLE);
    about.set_program_name(TITLE);

    about.set_website("http://gtableauparm.googlecode.com");

    //TODO set window icon
   

    /* set logo picture */
    Glib::RefPtr<Gdk::Pixbuf> logo;
    logo = Gdk::Pixbuf::create_from_file(APP_ICON128);
    about.set_logo(logo);
    

    about.run();
    about.hide();

}

void TP_main::on_menu_choices_bridge() {
    Glib::ustring message;
    if (m_refChoiceBridge->get_active())
        message = "Bridge was selected.";

    else
        message = "Bridge was deselected";
    tp_DeviceTreeView.hideColumn(BRIDGE);
    std::cout << message << std::endl;
}

void TP_main::on_menu_choices_device() {
    Glib::ustring message;
    if (m_refChoiceDevice->get_active()) {
        message = "device was selected.";

    } else
        message = "device was deselected";
    tp_DeviceTreeView.hideColumn(DEVICE);
    std::cout << message << std::endl;
}

void TP_main::on_menu_choices_vendor() {
    Glib::ustring message;
    if (m_refChoiceVendor->get_active()) {
        message = "vendor was selected.";

    } else
        message = "vendor was deselected";
    tp_DeviceTreeView.hideColumn(VENDOR);
    std::cout << message << std::endl;
}

void TP_main::on_menu_choices_model() {
    Glib::ustring message;
    if (m_refChoiceModel->get_active()) {
        message = "model was selected.";

    } else
        message = "model was deselected";
    tp_DeviceTreeView.hideColumn(MODEL);
    std::cout << message << std::endl;
}

void TP_main::on_menu_choices_size() {
    Glib::ustring message;
    if (m_refChoiceSize->get_active()) {
        message = "size was selected.";

    } else
        message = "size was deselected";
    tp_DeviceTreeView.hideColumn(SIZE);
    std::cout << message << std::endl;
}

void TP_main::on_menu_choices_writeblk() {
    Glib::ustring message;
    if (m_refChoiceWriteblk->get_active()) {
        message = "writeblk was selected.";

    } else
        message = "writeblk was deselected";
    tp_DeviceTreeView.hideColumn(WRITEBLK);
    std::cout << message << std::endl;
}

void TP_main::on_menu_choices_hpa() {
    Glib::ustring message;
    if (m_refChoiceHpa->get_active()) {
        message = "hpa was selected.";

    } else
        message = "hpa was deselected";
    tp_DeviceTreeView.hideColumn(HPAIU);
    std::cout << message << std::endl;
}

void TP_main::on_menu_choices_dco() {
    Glib::ustring message;
    if (m_refChoiceDco->get_active()) {
        message = "dco was selected.";

    } else
        message = "dco was deselected";
    tp_DeviceTreeView.hideColumn(DCOIU);
    std::cout << message << std::endl;
}

void TP_main::on_menu_choices_sec() {
    Glib::ustring message;
    if (m_refChoiceSec->get_active()) {
        message = "security was selected.";

    } else
        message = "security was deselected";
    tp_DeviceTreeView.hideColumn(SECIU);
    std::cout << message << std::endl;
}
//////////////
//printing
//////////////

void TP_main::on_menu_file_page_setup() {
    //Show the page setup dialog, asking it to start with the existing settings:
    Glib::RefPtr<Gtk::PageSetup> new_page_setup =
            Gtk::run_page_setup_dialog(*this, tpg_refPageSetup, tpg_refSettings);

    //Save the chosen page setup dialog for use when printing, previewing, or
    //showing the page setup dialog again:
    tpg_refPageSetup = new_page_setup;
}

void TP_main::on_menu_file_print_preview() {
    if (tp_DeviceTreeView.somethingSelected()) {
        print_or_preview(Gtk::PRINT_OPERATION_ACTION_PREVIEW);
    } else {
        Gtk::MessageDialog dia(*this, "No device selected!!",false,
                Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, false);
        dia.set_secondary_text("Pleace select a device in the list.");
        dia.set_title("Warning");
        dia.run();
    }
}

void TP_main::on_menu_file_print() {
    if (tp_DeviceTreeView.somethingSelected()) {
        print_or_preview(Gtk::PRINT_OPERATION_ACTION_PRINT_DIALOG);
    } else {
        Gtk::MessageDialog dia(*this, "No device selected!!",true,
                Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
        dia.set_secondary_text("Pleace select a device in the list.");
        dia.set_title("Warning");
        dia.run();
    }
}

void TP_main::on_printoperation_status_changed(
        const Glib::RefPtr<PrintFormOperation>& operation) {
    Glib::ustring status_msg;

    if (operation->is_finished()) {
        status_msg = "Print job completed.";
    } else {
        //You could also use get_status().
        status_msg = operation->get_status_string();
    }

    tpg_Statusbar.push(status_msg, tpg_ContextId);
}

void TP_main::on_printoperation_done(Gtk::PrintOperationResult result,
        const Glib::RefPtr<PrintFormOperation>& operation) {
    //Printing is "done" when the print data is spooled.

    if (result == Gtk::PRINT_OPERATION_RESULT_ERROR) {
        Gtk::MessageDialog err_dialog(*this, "Error printing form", false,
                Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
        err_dialog.run();
    } else if (result == Gtk::PRINT_OPERATION_RESULT_APPLY) {
        //Update PrintSettings with the ones used in this PrintOperation:
        tpg_refSettings = operation->get_print_settings();
    }

    if (!operation->is_finished()) {
        //We will connect to the status-changed signal to track status
        //and update a status bar. In addition, you can, for example,
        //keep a list of active print operations, or provide a progress dialog.
        operation->signal_status_changed().connect(sigc::bind(sigc::mem_fun(*this,
                &TP_main::on_printoperation_status_changed),
                operation));
    }
}

void TP_main::print_or_preview(Gtk::PrintOperationAction print_action) {
    //Create a new PrintOperation with our PageSetup and PrintSettings:
    //(We use our derived PrintOperation class)
    Glib::RefPtr<PrintFormOperation> print = PrintFormOperation::create();

    print->set_device(tp_DeviceTreeView.get_SelectedDeviceIterator());
    print->set_track_print_status();
    print->set_default_page_setup(tpg_refPageSetup);
    print->set_print_settings(tpg_refSettings);

    print->signal_done().connect(sigc::bind(sigc::mem_fun(*this,
            &TP_main::on_printoperation_done), print));

    try {
        print->run(print_action /* print or preview */, *this);
    } catch (const Gtk::PrintError& ex) {
        //See documentation for exact Gtk::PrintError error codes.
        std::cerr << "An error occurred while trying to run a print operation:"
                << ex.what() << std::endl;
    }

}
